package com.elanfox.littlereporter.service.impl;

import com.elanfox.littlereporter.common.CodeDescEnumHelper;
import com.elanfox.littlereporter.common.GradeType;
import com.elanfox.littlereporter.entity.ContributionPO;
import com.elanfox.littlereporter.entity.ContributionPO_;
import com.elanfox.littlereporter.model.ContributionSearchCondition;
import com.elanfox.littlereporter.repository.ContributionRepository;
import com.elanfox.littlereporter.service.ContributionService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.persistence.criteria.Predicate;
import java.util.ArrayList;
import java.util.List;

/**
 * @author allan
 * @date 2018-03-25
 */
@Service
public class ContributionServiceImpl implements ContributionService {
    @Autowired
    private ContributionRepository contributionRepository;

    @Override
    public ContributionPO save(ContributionPO contributionPO) {
        return contributionRepository.save(contributionPO);
    }

    @Override
    public Page<ContributionPO> findAll(int pageIndex, int pageSize, ContributionSearchCondition searchCondition) {
        Specification<ContributionPO> specification = ((root, query, cb) -> {
            List<Predicate> predicates = new ArrayList<>();
            if (!StringUtils.isEmpty(searchCondition.getSchool())) {
                predicates.add(cb.like(root.get(ContributionPO_.school), likeFormat(searchCondition.getSchool())));
            }
            if (searchCondition.getGradeType() != -1) {
                GradeType gradeType = CodeDescEnumHelper.getEnumTypeByCode(GradeType.class, searchCondition.getGradeType());
                predicates.add(cb.equal(root.get(ContributionPO_.gradeType), gradeType));
            }
            if (!StringUtils.isEmpty(searchCondition.getClassName())) {
                predicates.add(cb.like(root.get(ContributionPO_.className), likeFormat(searchCondition.getClassName())));
            }
            if (!StringUtils.isEmpty(searchCondition.getReporterName())) {
                predicates.add(cb.like(root.get(ContributionPO_.reporterName), likeFormat(searchCondition.getReporterName())));
            }
            if (!StringUtils.isEmpty(searchCondition.getReporterNum())) {
                predicates.add(cb.like(root.get(ContributionPO_.reporterNum), likeFormat(searchCondition.getReporterNum())));
            }
            if (!StringUtils.isEmpty(searchCondition.getKeyword())) {
                predicates.add(cb.or(
                        cb.like(root.get(ContributionPO_.reporterNum), likeFormat(searchCondition.getKeyword())),
                        cb.like(root.get(ContributionPO_.reporterName), likeFormat(searchCondition.getKeyword()))
                ));
            }

            return cb.and(predicates.toArray(new Predicate[predicates.size()]));
        });

        return contributionRepository.findAll(specification, new PageRequest(pageIndex - 1, pageSize, new Sort(Sort.Direction.DESC, "id")));
    }

    @Override
    public ContributionPO findById(int id) {
        return contributionRepository.findOne(id);
    }

    protected String likeFormat(String field) {
        return "%" + field + "%";
    }
}
